package com.hongyi.web.service.impl;


import com.hongyi.web.dto.SysMenDto;
import com.hongyi.web.mapper.SysMenuMapper;
import com.hongyi.web.mapper.SysRoleMenuMapper;
import com.hongyi.web.pojo.SysMenu;
import com.hongyi.web.query.SysMenuQueryDto;
import com.hongyi.web.service.ISysMenuService;
import com.hongyi.web.utils.StringUtils;
import com.hongyi.web.vo.SysMenuVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 菜单 业务层处理
 *
 * @author xingnuo
 */
@Service
public class SysMenuServiceImpl implements ISysMenuService
{

    @Autowired
    private SysMenuMapper menuMapper;

    @Autowired
    private SysRoleMenuMapper roleMenuMapper;



    /**
     * 查询系统菜单列表
     *
     * @param sysMenuQueryDto 菜单信息
     * @return 菜单列表
     */
    @Override
    public List<SysMenuVo> selectMenuList(SysMenuQueryDto sysMenuQueryDto) {
        List<SysMenu> sysMenus = menuMapper.selectMenuList(sysMenuQueryDto);

        List<SysMenuVo> sysMenuVos = new ArrayList<>();

        for (SysMenu sysMenu : sysMenus) {
            SysMenuVo sysMenuVo = new SysMenuVo();
            BeanUtils.copyProperties(sysMenu, sysMenuVo);
            sysMenuVos.add(sysMenuVo);

        }
        return buildMenuTree(sysMenuVos);
    }




    /**
     * 构建前端所需要树结构
     *
     * @param list 菜单列表
     * @return 树结构列表
     */
    @Override
    public List<SysMenuVo> buildMenuTree(List<SysMenuVo> list)
    {
        List<SysMenuVo> returnList = new ArrayList();
        List<Long> tempList = list.stream().map(SysMenuVo::getMenuId).collect(Collectors.toList());
        for (SysMenuVo sysMenuVo : list)
        {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(sysMenuVo.getParentId()))
            {
                recursionFn(list, sysMenuVo);

                returnList.add(sysMenuVo);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = list;
        }
        return returnList;
    }
    /**
     * 根据菜单ID查询信息
     *
     * @param menuId 菜单ID
     * @return 菜单信息
     */
    @Override
    public SysMenDto selectMenuById(Long menuId)
    {
        SysMenu sysMenu = menuMapper.selectMenuById(menuId);
        SysMenDto sysMenuDto = new SysMenDto();
        BeanUtils.copyProperties(sysMenu,sysMenuDto);
        return sysMenuDto;
    }

    /**
     * 是否存在菜单子节点
     *
     * @param menuId 菜单ID
     * @return 结果
     */
    @Override
    public boolean hasChildByMenuId(Long menuId)
    {
        int result = menuMapper.hasChildByMenuId(menuId);
        return result > 0;
    }

    /**
     * 查询菜单使用数量
     *
     * @param menuId 菜单ID
     * @return 结果
     */
    @Override
    public boolean checkMenuExistRole(Long menuId)
    {
        int result = roleMenuMapper.checkMenuExistRole(menuId);
        return result > 0;
    }

    /**
     * 新增保存菜单信息
     *
     * @param sysMenuDto 菜单信息
     * @return 结果
     */
    @Override
    public int insertMenu(SysMenDto sysMenuDto)
    {
        SysMenu menu = new SysMenu();
        BeanUtils.copyProperties(sysMenuDto, menu);
        return menuMapper.insertMenu(menu);
    }

    /**
     * 修改保存菜单信息
     *
     * @param sysMenDto 菜单信息
     * @return 结果
     */
    @Override
    public int updateMenu(SysMenDto sysMenDto)
    {
        SysMenu menu = new SysMenu();
        BeanUtils.copyProperties(sysMenDto, menu);
        return menuMapper.updateMenu(menu);
    }

    /**
     * 删除菜单管理信息
     *
     * @param menuId 菜单ID
     * @return 结果
     */
    @Override
    public int deleteMenuById(Long menuId)
    {
        return menuMapper.deleteMenuById(menuId);
    }

    /**
     * 校验菜单名称是否唯一
     *
     * @param menu 菜单信息
     * @return 结果
     */
    @Override
    public boolean checkMenuNameUnique(SysMenDto menu)
    {
        Long menuId = StringUtils.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
        SysMenu info = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId());
        if (StringUtils.isNotNull(info) && info.getMenuId().longValue() != menuId.longValue())
        {
            return false;
        }
        return true;
    }



    /**
     * 递归列表
     *
     * @param list 分类表
     * @param t 子节点
     */
    private void recursionFn(List<SysMenuVo> list, SysMenuVo t)
    {
        // 得到子节点列表
        List<SysMenuVo> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenuVo tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysMenuVo> getChildList(List<SysMenuVo> list, SysMenuVo t)
    {
        List<SysMenuVo> tlist = new ArrayList();
        Iterator<SysMenuVo> it = list.iterator();
        while (it.hasNext())
        {
            SysMenuVo n = (SysMenuVo) it.next();
            if (StringUtils.isNotNull(n.getParentId()) &&n.getParentId().longValue() == t.getMenuId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysMenuVo> list, SysMenuVo t)
    {
        return getChildList(list, t).size() > 0;
    }
}

